package com.alibaba.basic.service.impl;

import com.alibaba.basic.constant.BaseConstants;
import com.alibaba.basic.dto.SMSCodeDto;
import com.alibaba.basic.exception.BusinessException;
import com.alibaba.basic.service.IVerifyCodeService;
import com.alibaba.basic.util.StrUtils;
import com.alibaba.basic.util.VerifyCodeUtils;
import com.alibaba.user.domain.User;
import com.alibaba.user.mapper.UserMapper;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {

    @Resource
    private UserMapper userMapper;
    @Resource
    private RedisTemplate redisTemplate;
    @Override
    public String getImgCode(String key) {
       //判断验证码是非为空
        if (StringUtils.isEmpty(key)){
            throw new BusinessException("数据异常");
        }
        //生产验证码 设置5位数 验证码
        String code = VerifyCodeUtils.generateVerifyCode(5);
        //存放redis 设置过期时间5minutes
        redisTemplate.opsForValue().set(key, code, 5, TimeUnit.MINUTES);
        //把验证码的值合并到图片，使用Base64编码。并返回base64编码的字符串
        return VerifyCodeUtils.VerifyCode(110, 40, code);
    }

    /**
     * 短信验证码验证流程
     * @param smsCodeDto
     */
    @Override
    public void sendSmsCode(SMSCodeDto smsCodeDto) {

        String imageCode = smsCodeDto.getImageCode();
        String phone = smsCodeDto.getPhone();
        String imageCodeKey = smsCodeDto.getImageCodeKey();
        //非空判断
        if (StringUtils.isEmpty(imageCode) || StringUtils.isEmpty(phone) ||StringUtils.isEmpty(imageCodeKey)){
            throw new BusinessException("相关参数不可为空");
        }
        //2.校验 - 图形验证码校验 - 是否过期
        Object imageCodeOfRedis = redisTemplate.opsForValue().get(imageCodeKey);
        if(imageCodeOfRedis == null){
            throw new BusinessException("图形验证码已失效");
        }
        //3.校验 - 图形验证码校验 - 是否正确
        if(!imageCodeOfRedis.toString().equalsIgnoreCase(imageCode)){
            throw new BusinessException("图形验证码错误");
        }
        //4.校验 - 手机号码是否注册过
        //为什么要用User不用Logininfo：其实可以用Logininfo去查询，但是需要多传入一个type
        User user=userMapper.findByPhone(phone);
        if (user!=null){
            throw new BusinessException("此号码已经被注册过，请直接登录！");
        }
        //4.根据电话号码拼接业务键，去redis中获取对应的value值，判断是否存在
        String phoneCodeKey = BaseConstants.VerifyCodeConstant.BUSINESS_REGISTER_KEY + phone;
        Object phoneCodeValue = redisTemplate.opsForValue().get(phoneCodeKey);
        /**
         * 如果值不存在则 生成新的验证码
         * 如果值存在 则 通过;分割 之前的 value值
         */
        String code = null;  //要发送给用户的验证码
        if (phoneCodeValue==null){//第一次发送 or 手机验证码过期了
            //生成新的验证码
            code = StrUtils.getComplexRandomString(6);
        } else {
            //没有过期
            //验证是否过了重发时间
            //以前保存的时间
            long passTime = Long.parseLong(phoneCodeValue.toString().split(":")[1]);
            long nowTime = System.currentTimeMillis();
            if(nowTime - passTime < 1*60*1000){
                throw new BusinessException("请勿频繁获取验证码");
            } else {
                code = phoneCodeValue.toString().split(":")[0];
            }
        }
        //7.将验证码存入redis：【register:18725556563 - 9527:1233555555】
        //刷新过期时间
        redisTemplate.opsForValue()
                .set(BaseConstants.VerifyCodeConstant.BUSINESS_REGISTER_KEY + phone , code+":"+System.currentTimeMillis());

        //8.调用SmsUtils发送短信
        //SmsUtil.sendSms(phone,"手机验证码为：" + code + ",请在3分钟内使用!!!");
        System.out.println("手机验证码为：" + code + ",请在3分钟内使用!!!");

    }

    @Override
    public void binderSmsCode(SMSCodeDto smsDto) {
        String phone = smsDto.getPhone();

        //1.校验 - 空值校验
        if(StringUtils.isEmpty(phone)){
            throw new BusinessException("手机号码不能为空!!!");
        }


        //5.获取手机验证码 - 判断是否过期 // 9527:1233555555
        Object redisSmsCode = redisTemplate.opsForValue().get(BaseConstants.VerifyCodeConstant.BUSINESS_BINDER_PREFIX + phone);
        String code = null;
        if(redisSmsCode == null){//第一次发送 or 手机验证码过期了
            //过期了就用新的验证码
            code = StrUtils.getComplexRandomString(6);
        }else{//没有过期
            //验证是否过了重发时间
            //以前保存的时间
            long redisTime = Long.parseLong(redisSmsCode.toString().split(":")[1]);
            //现在的时间
            long nowTime = System.currentTimeMillis();
            //6.没有过期 - 判断是否过了重发时间
            if((nowTime-redisTime)<1*60*1000){//没有过重发时间
                throw new BusinessException("请勿重复获取验证码!!!");
            }else{
                //没有过期就用以前的验证码
                code = redisSmsCode.toString().split(":")[0];
            }
        }

        //7.将验证码存入redis：【register:18725556563 - 9527:1233555555】
        //刷新了过期时间
        redisTemplate.opsForValue().set(BaseConstants.VerifyCodeConstant.BUSINESS_BINDER_PREFIX + phone,code+":"+System.currentTimeMillis(),3,TimeUnit.MINUTES);

        //8.调用SmsUtils发送短信
        //SmsUtil.sendSms(phone,"手机验证码为：" + code + ",请在3分钟内使用!!!");
        System.out.println("手机验证码为：" + code + ",请在3分钟内使用!!!");
    }

}
